#!/usr/bin/env python
# -*- coding: utf8 -*-
# title       :
# description :
# author      :'ShenMeng'

import os
import sys
from functools import partial

from PySide import QtGui, QtCore
from .data.asset_data_enum import get_asset_library_data, get_asset_type_data, get_asset_name_data, get_asset_step_data
from .pyuic.asset_library_widget import Ui_library_widget
from .library_style import STANDARD_STYLE
from .preview_widget import PreviewWidget
from .list_view_thumb_delegate import ListViewThumbDelegate
from .list_view_list_delegate import ListViewListDelegate
from .overlay_widget import OverlayWidget as my_overlay_widget
from .pyuic import resources_rc


class LibraryWidget(QtGui.QDialog):
    def __init__(self, parent=None, library_data=[]):
        super(LibraryWidget, self).__init__(parent)
        self.setStyleSheet(STANDARD_STYLE)
        self.setContentsMargins(0,0,0,0)
        self.setMouseTracking(True)

        ###---initialize---###
        self._root_path = library_data[0]
        self._action_manager = library_data[1]
        self._filter_item = ['designs', 'alembics', 'shaders', 'textures', 'rigs', 'loops']
        self._filter_item.sort()
        self.asset_step_view_item_dict = {}
        self.asset_library_view_item_dict = {}
        self.current_uuid = None
        self._refresh = False

        ###---initialize ui---###
        self._ui = Ui_library_widget()
        self._ui.setupUi(self)
        top_style = """
                *{background:rgb(75,75,75);border:none;}
                QFrame#right_top_frame{border-bottom:1px solid rgb(20,20,20);min-height:30px;}

                QLineEdit#search_line{
                    background-color: rgb(30,30,30);
                    border-width: 1px;
                    border-radius: 5px;
                    margin-top:4px;
                    margin-bottom:4px;
                    }
                /*QLineEdit:active{background-color: rgb(30,30,30);}
                QLineEdit:focus{background-color: rgb(30,30,30);}*/
                """
        self.setWindowTitle('Asset Library')
        self._ui.left_top_frame.setStyleSheet(top_style)
        self._ui.middle_top_frame.setStyleSheet(top_style)
        self._ui.right_top_frame.setStyleSheet(top_style)
        # self._ui.right_frame.setStyleSheet("QFrame{border:none;}QListView{border:1px solid red;}")
        self._ui.asset_filter_view.setStyleSheet("background:rgb(40,40,40);")
        self._ui.asset_version_view.setStyleSheet("QListView{background:rgb(40,40,40)}")

        self._ui.splitter.setHandleWidth(1)
        self._ui.splitter.handle(1).setDisabled(1)
        self._ui.splitter.handle(2).setDisabled(1)
        self._ui.splitter.handle(0).setDisabled(1)
        self._ui.splitter.setStyleSheet("QSplitter::handle{background:rgb(20,20,20);}")

        ###---expand btn---###
        self.left_area_show = True
        self.right_area_show = True
        self.left_handle_btn = None
        self.right_handle_btn = None
        self.left_arrow_icon = QtGui.QIcon(":/icons/scroll_left")
        self.right_arrow_icon = QtGui.QIcon(":/icons/scroll_right")

        ###---Asset library view---###
        self.asset_library_view_model = QtGui.QStandardItemModel()
        self._ui.asset_library_view.setModel(self.asset_library_view_model)
        self._ui.asset_library_view.setEditTriggers(QtGui.QTreeWidget.NoEditTriggers)
        self._ui.asset_library_view.setFocusPolicy(QtCore.Qt.NoFocus)
        self._ui.asset_library_view.setRootIsDecorated(1)
        self._ui.asset_library_view.setAlternatingRowColors(0)
        self.asset_library_view_sel_model = self._ui.asset_library_view.selectionModel()
        self.asset_library_view_sel_model.currentChanged.connect(self.asset_library_view_sel_changed)
        # 右键菜单
        # self._ui.folder_tree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        # self._ui.folder_tree.customContextMenuRequested.connect(self.folder_tree_context_menu)

        ###---asset step view---###
        self.asset_step_view_model = QtGui.QStandardItemModel()
        self._ui.asset_step_view.setModel(self.asset_step_view_model)
        self._ui.asset_step_view.setViewMode(QtGui.QListView.IconMode)
        self._ui.asset_step_view.setIconSize(QtCore.QSize(256,234))
        self._ui.asset_step_view.setGridSize(QtCore.QSize(261,239))
        self._ui.asset_step_view.setMovement(QtGui.QListView.Static)
        self._ui.asset_step_view.setResizeMode(QtGui.QListView.Adjust)
        self._ui.asset_step_view.setFlow(QtGui.QListView.LeftToRight)
        asset_step_view_delegate = ListViewThumbDelegate(self._ui.asset_step_view, self._action_manager)
        self._ui.asset_step_view.setItemDelegate(asset_step_view_delegate)
        self._ui.asset_step_view.doubleClicked.connect(self.on_asset_step_view_double_clicked)
        self.asset_step_view_sel_model = self._ui.asset_step_view.selectionModel()
        self.asset_step_view_sel_model.selectionChanged.connect(self.asset_step_view_selection_changed)
        self.asset_step_view_overlay = my_overlay_widget(self._ui.asset_step_view)
        # # 右键菜单
        # self._ui.file_view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        # # STEP 2 connect signal
        # self._ui.file_view.customContextMenuRequested.connect(self.file_view_context_menu)

        ###---Asset version view---###
        self.asset_version_view_model = QtGui.QStandardItemModel()
        self._ui.asset_version_view.setModel(self.asset_version_view_model)
        asset_version_view_delegate = ListViewListDelegate(self._ui.asset_version_view, self._action_manager)
        self._ui.asset_version_view.setItemDelegate(asset_version_view_delegate)

        ###---Asset preview---###
        self.preview_frame = PreviewWidget()
        self._ui.preview_layout.addWidget(self.preview_frame)
        self._ui.asset_actions_btn.setVisible(0)
        self._ui.asset_playback_btn.setVisible(0)

        ###---scale icon slider---###
        self._ui.scale_slider.setMinimum(1)
        self._ui.scale_slider.setMaximum(4)
        self._ui.scale_slider.setPageStep(5)
        self._ui.scale_slider.setOrientation(QtCore.Qt.Horizontal)
        self._ui.scale_slider.setTickPosition(QtGui.QSlider.TicksAbove)
        self._ui.scale_slider.setTickInterval(1)
        self._ui.scale_slider.setValue(2)
        self._ui.scale_slider.valueChanged.connect(self.scale_list_item_size)

        ###---Asset search line---###
        self._ui.search_line.textChanged.connect(self.on_search_line_changed)
        self._ui.clear_search_line.clicked.connect(self._ui.search_line.clear)
        self._ui.search_line.setPlaceholderText("Search...")
        self._ui.search_btn.clicked.connect(self.on_search_btn_clicked)

        ###---Asset filter view---###
        self._ui.asset_filter_view.itemClicked.connect(self.refresh_asset_step_view)

        ###---initialize func---###
        self._create_ui()
        self.overlay_display(1)
        self._display_version_view()

    def create_collapse_expend_btn(self):
        """
        创建左右伸缩按钮,用于隐藏左边树形大纲列表和右边属性面板
        :return:
        """
        if self.left_handle_btn and self.right_handle_btn:
            return
        # left
        self.left_handle_btn = QtGui.QPushButton(self)
        self.left_handle_btn.setFocusPolicy(QtCore.Qt.NoFocus)
        self.left_handle_btn.setFlat(1)
        self.left_handle_btn.hide()
        self.left_handle_btn.setFixedSize(13, 150)
        self.left_handle_btn.setIconSize(self.left_handle_btn.size())
        self.left_handle_btn.setStyleSheet("""border:none;background-color:rgba(0,120,215,100);
                                              border-top-right-radius:13px;
                                              border-bottom-right-radius:13px;
                                              """)
        self.left_handle_btn.setIcon(self.left_arrow_icon)
        left_handle_btn_pos = self.get_btn_pos('left', 'show')
        self.left_handle_btn.move(left_handle_btn_pos[0], left_handle_btn_pos[1])
        self.left_handle_btn.clicked.connect(partial(self.collapse_expend, True))
        # right
        self.right_handle_btn = QtGui.QPushButton(self)
        self.right_handle_btn.setFlat(1)
        self.right_handle_btn.setFocusPolicy(QtCore.Qt.NoFocus)
        self.left_handle_btn.hide()
        self.right_handle_btn.setFixedSize(13, 150)
        self.right_handle_btn.setIconSize(self.right_handle_btn.size())
        self.right_handle_btn.setStyleSheet("""border:none;background-color:rgba(0,120,215,100);
                                               border-top-left-radius:13px;
                                               border-bottom-left-radius:13px;
                                               """)
        self.right_handle_btn.setIcon(self.right_arrow_icon)
        right_handle_btn_pos = self.get_btn_pos('right', 'show')
        self.right_handle_btn.move(right_handle_btn_pos[0], right_handle_btn_pos[1])
        self.right_handle_btn.clicked.connect(partial(self.collapse_expend, False))
        # self._ui.open_folder_btn.clicked.connect(self.on_open_folder_btn_clicked)

    def on_open_folder_btn_clicked(self):
        """
        打开文件夹当前选择的资产目录
        :return:
        """
        if self.tree_sel_model.hasSelection():
            index = self.tree_sel_model.currentIndex()
            item = self._ui.folder_tree.itemFromIndex(index)
            data = item.data(1, 1)
            os.startfile(data.path)
        else:
            os.startfile(self._root_path)

    def _create_ui(self):
        """
        初始化ui
        :return:
        """
        self._create_file_type_item()
        self._create_library_view_item()

    def _create_file_type_item(self):
        """
        过滤视图创建
        :return:
        """
        for i in ['designs', 'alembics', 'shaders', 'textures', 'rigs', 'loops']:
            item = QtGui.QListWidgetItem(i.capitalize())
            item.setCheckState(QtCore.Qt.Checked)
            item.setData(3, True)
            self._ui.asset_filter_view.addItem(item)

    def _create_library_view_item(self):
        for path in self._root_path:
            self._create_library_item(path)

    def _create_library_item(self, path):
        data = get_asset_library_data(path)
        item = QtGui.QStandardItem()
        item.setText(data.name)
        item.setIcon(QtGui.QIcon(':/icons/refresh.png'))
        item.setData(data, 3)
        item.setData(False, 4)
        self.asset_library_view_model.appendRow(item)
        self.asset_library_view_item_dict[data.item_uuid] = item

    def asset_library_view_sel_changed(self, index):
        self.overlay_display(0)
        self._display_version_view()
        item = self.asset_library_view_model.itemFromIndex(index)
        self.asset_step_view_model.clear()
        item_data = item.data(3)
        # self.update_info(item_data)
        item_uuid = item_data.item_uuid
        if not item.data(4):
            self.asset_step_view_item_dict[item_uuid] = []
            if item_data.item_type == 'library':
                data = get_asset_type_data(item_data)
                icon_path = ':/icons/refresh.png'
            elif item_data.item_type == 'type':
                data = get_asset_name_data(item_data)
                icon_path = ':/icons/icon_Asset_dark.png'
            else:
                self.asset_step_view_item_dict[item_uuid] = {}
                data_dict = get_asset_step_data(item_data)
                for step in data_dict:
                    key_dict = []
                    step_data = data_dict.get(step)
                    for data in step_data:
                        asset_step_view_item = QtGui.QStandardItem()
                        asset_step_view_item.setData(data, 3)
                        key_dict.append(asset_step_view_item)
                    self.asset_step_view_item_dict[item_uuid][step]=key_dict
                self.current_uuid = item_uuid
                item.setData(True, 4)
                self._refresh = True
                self._refresh_asset_step_view()
                return
            if not data:
                self.overlay_display(1)
            for type_data in data:
                asset_step_view_item = QtGui.QStandardItem()
                asset_step_view_item.setData(type_data, 3)
                self.asset_step_view_item_dict[item_uuid].append(asset_step_view_item)
                self.asset_step_view_model.appendRow(asset_step_view_item)
                library_item = QtGui.QStandardItem()
                library_item.setText(type_data.name)
                library_item.setIcon(QtGui.QIcon(icon_path))
                item.appendRow(library_item)
                library_item.setData(type_data, 3)
                library_item.setData(False, 4)
                self.asset_library_view_item_dict[type_data.item_uuid] = library_item
            item.setData(True, 4)
            item.setIcon(QtGui.QIcon(':/icons/icon_Folder.png'))
        else:
            item_list = self.asset_step_view_item_dict.get(item_uuid)
            if not item_list:
                self.overlay_display(1)
                return
            if item_data.item_type == 'asset':
                self._refresh = True
                self.current_uuid = item_uuid
                self._refresh_asset_step_view()
                return
            for i in item_list:
                self.asset_step_view_model.appendRow(i)
        self._refresh = False

    def update_info(self, data=None):
        """
        详细信息设置
        :param data:
        :return:
        """
        self._ui.asset_info.setText('')
        def __make_table_row(left, right):
            """
            Helper method to make a detail table row
            """
            return "<tr><td><b style='color:#2C93E2'>%s</b>&nbsp;</td><td>%s</td></tr>" % (left, right)
        if data:
            if data.item_type == 'variant':
                # self._ui.label.setEnabled(1)
                msg = ""
                msg += __make_table_row("Name", "%s" % data.name)
                msg += __make_table_row("Version", "%s" % data.version)
                msg += __make_table_row("Asset", data.asset_name)
                msg += __make_table_row("Step", data.asset_step.capitalize())
                # msg += __make_table_row("Description", "")
            else:
                msg = ""
                msg += __make_table_row("Name", "%s" % data.name)
                msg += __make_table_row("Status", "Final")
                # msg += __make_table_row("Description", "")
            self._ui.asset_info.setText("<table>%s</table>" % msg)

    def on_asset_step_view_double_clicked(self, index):
        """
        资产视图双击事件
        :param index:
        :return:
        """
        item = self.asset_step_view_model.itemFromIndex(index)
        data = item.data(3)
        if data.item_type != 'variant':
            t_item = self.asset_library_view_item_dict[data.item_uuid]
            item_index = self.asset_library_view_model.indexFromItem(t_item)
            self.asset_library_view_sel_model.clearSelection()
            self.asset_library_view_sel_model.setCurrentIndex(item_index, QtGui.QItemSelectionModel.SelectCurrent)

    def refresh_asset_step_view(self, item):
        """
        资产视图显示更新
        :param item:
        :return:
        """
        if item.checkState() == QtCore.Qt.CheckState.Checked:
            if not item.data(3):
                item.setData(3, True)
                step = item.text().lower()
                if not step in self._filter_item:
                    self._filter_item.append(step)
                    self._filter_item.sort()
                    if self._refresh:
                        self._refresh_asset_step_view()
        else:
            if item.data(3):
                item.setData(3, False)
                step = item.text().lower()
                if step in self._filter_item:
                    self._filter_item.remove(step)
                    self._filter_item.sort()
                    if self._refresh:
                        self._refresh_asset_step_view()

    def _refresh_asset_step_view(self):
        """
        资产视图数据更新
        :return:
        """
        self.asset_step_view_model.clear()
        self.overlay_display(0)
        if self._filter_item:
            data_dict = self.asset_step_view_item_dict.get(self.current_uuid)
            if not data_dict:
                self.overlay_display(1)
                return
            for item in self._filter_item:
                item_list = data_dict.get(item)
                if item_list:
                    for i in item_list:
                        self.asset_step_view_model.appendRow(i)

    def overlay_display(self, statue):
        """
        提示功能
        :param statue:
        :return:
        """
        if statue:
            self.asset_step_view_overlay.show_message_pixmap(QtGui.QPixmap(":/icons/no_publishes_found.png"))
        else:
            self.asset_step_view_overlay.hide()

    def _display_version_view(self, statue=0):
        self._ui.asset_version_view.setEnabled(statue)

    def asset_step_view_selection_changed(self, selected, deselected):
        """
        资产视图选择事件
        :param selected:
        :param deselected:
        :return:
        """
        selected_indexes = selected.indexes()
        self.asset_version_view_model.clear()
        self._display_version_view()
        if not selected_indexes:
            self.preview_frame.show_pixmap()
            self.update_info()
        else:

            item = self.asset_step_view_model.itemFromIndex(selected_indexes[0])
            data = item.data(3)
            self.update_info(data)
            if data.item_type == 'variant':
                self._display_version_view(1)
                version_list = data.version_list
                for version in version_list:
                    item = QtGui.QStandardItem()
                    item.setData(version, 3)
                    self.asset_version_view_model.appendRow(item)
                    image_path = data.path.replace(os.path.splitext(data.path)[1], '.png')
                    self.preview_frame.show_pixmap(image_path)
            else:
                self.preview_frame.show_pixmap(":/icons/folder_512x400.png")

    def scale_list_item_size(self, value):
        """
        缩放列表里面元素的大小
        :param value:
        :return:
        """
        # (scale_factor * 0.78125) + 34
        width = value*128
        height = value*100+34
        self._ui.asset_step_view.setIconSize(QtCore.QSize(width, height))
        self._ui.asset_step_view.setGridSize(QtCore.QSize(width+5, height+5))

    def on_search_btn_clicked(self):
        """
        点击搜索按钮时，去数据库查询匹配
        :return:
        """
        text = self._ui.search_line.text()
        if text:
            search_asset = SearchAsset(self._root_path, text)
            asset_data_list = search_asset.search()
            self.list_model.clear()
            for asset_data in asset_data_list:
                self._create_list_item(asset_data)

    def on_search_line_changed(self, *args):
        """
        当输入框没有输入的值时，还原列表元素
        :param args:
        :return:
        """
        text = self._ui.search_line.text()
        if not text:
            # syntax = QtCore.QRegExp.PatternSyntax(QtCore.QRegExp.RegExp)
            # regExp = QtCore.QRegExp(self._ui.search_line.text(), QtCore.Qt.CaseInsensitive, syntax)
            # self.proxy_model.setFilterRegExp(regExp)
            self.proxy_model.setFilterRegExp('')
            self.list_model.clear()
            self._tree_sel_changed(self._current_item)

    def showEvent(self, event):
        """
        界面显示的时候创建左右伸缩按钮,设置缩放滑杆的位置
        :param event:
        :return:
        """
        self.create_collapse_expend_btn()
        app = QtGui.QApplication.instance()
        app.installEventFilter(self)

    def get_btn_pos(self, btn='left', display='hide'):
        """
        实时计算获取左右伸缩按钮和缩放滑杆的位置
        :param btn:
        :param display:
        :return:
        """
        x = y = 0
        height = self._ui.middle_area.rect().bottom()/2 + self._ui.middle_area.mapTo(self, self._ui.middle_area.rect().topLeft()).y()
        # left
        if btn == 'left':
            if display == 'hide':
                x = self.getContentsMargins()[0] + 0
                y = height - self.left_handle_btn.height()/ 2
            elif display == 'show':
                x = self.getContentsMargins()[0] + self._ui.left_area.maximumWidth() + 0
                y = height - self.left_handle_btn.height()/2
        # right
        elif btn == 'right':
            if display == 'hide':
                x = self.width()-self.getContentsMargins()[0]-self.right_handle_btn.width()-0
                y = height-self.right_handle_btn.height()/2
            elif display == 'show':
                x = self.width()-self._ui.right_area.maximumWidth()-self.right_handle_btn.width()-self.getContentsMargins()[2]-1
                y = height-self.right_handle_btn.height()/2
        return [x, y]

    def resizeEvent(self, event):
        """
        左右伸缩按钮和缩放滑杆位置随窗口大小的改变实时的更新
        :param event:
        :return:
        """
        if not self.left_handle_btn and not self.right_handle_btn:
            return
        # left
        if self.right_area_show:
            pos = self.get_btn_pos('right', 'show')
            self.right_handle_btn.move(pos[0], pos[1])
        else:
            pos = self.get_btn_pos('right', 'hide')
            self.right_handle_btn.move(pos[0], pos[1])
        # right
        if self.left_area_show:
            pos = self.get_btn_pos('left', 'show')
            self.left_handle_btn.move(pos[0], pos[1])
        else:
            pos = self.get_btn_pos('left', 'hide')
            self.left_handle_btn.move(pos[0], pos[1])

    def collapse_expend(self, btn):
        """
        左右两边区域展开或隐藏
        :param btn:
        :return:
        """
        # left
        if btn:
            if self.left_area_show:
                pos = self.get_btn_pos('left', 'hide')
                self.left_handle_btn.move(pos[0], pos[1])
                self.left_area_show = False
                self._ui.splitter.handle(1).moveSplitter(-2)
                self.left_handle_btn.setIcon(self.right_arrow_icon)
                self.left_handle_btn.hide()
                self._ui.asset_library_view.setVisible(0)
            else:
                pos = self.get_btn_pos('left', 'show')
                self.left_handle_btn.move(pos[0], pos[1])
                self.left_area_show = True
                self._ui.splitter.handle(1).moveSplitter(self._ui.left_area.maximumWidth())
                self.left_handle_btn.setIcon(self.left_arrow_icon)
                self.left_handle_btn.show()
                self._ui.asset_library_view.setVisible(1)
        # right
        else:
            if self.right_area_show:
                pos = self.get_btn_pos('right', 'hide')
                self.right_handle_btn.move(pos[0], pos[1])
                self.right_area_show = False
                self._ui.splitter.handle(2).moveSplitter(self.width())
                self.right_handle_btn.setIcon(self.left_arrow_icon)
                self.right_handle_btn.hide()
                self._ui.right_frame.setVisible(0)
            else:
                pos = self.get_btn_pos('right', 'show')
                self.right_handle_btn.move(pos[0], pos[1])
                self.right_area_show = True
                self._ui.splitter.handle(2).moveSplitter(self.width()-self._ui.right_area.maximumWidth())
                self.right_handle_btn.setIcon(self.right_arrow_icon)
                self.right_handle_btn.show()
                self._ui.right_frame.setVisible(1)

    def eventFilter(self, obj, event):
        """
        设置左右伸缩按钮根据鼠标的位置来显示和隐藏
        :param obj:
        :param event:
        :return:
        """
        if event.type() == QtCore.QEvent.MouseMove:
            if not self.left_handle_btn and not self.right_handle_btn:
                return super(LibraryWidget, self).eventFilter(obj, event)
            # left
            btn_rect = self.left_handle_btn.rect()
            top_left = self.left_handle_btn.mapToGlobal(btn_rect.topLeft())
            bottom_right = self.left_handle_btn.mapToGlobal(btn_rect.bottomRight())
            rect = QtCore.QRect(top_left, bottom_right)
            if rect.contains(event.globalPos()):
                self.left_handle_btn.show()
            else:
                self.left_handle_btn.hide()
            # right
            btn_rect = self.right_handle_btn.rect()
            top_left = self.right_handle_btn.mapToGlobal(btn_rect.topLeft())
            bottom_right = self.right_handle_btn.mapToGlobal(btn_rect.bottomRight())
            rect = QtCore.QRect(top_left, bottom_right)
            if rect.contains(event.globalPos()):
                self.right_handle_btn.show()
            else:
                self.right_handle_btn.hide()
        return super(LibraryWidget, self).eventFilter(obj, event)